home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 410_01 / part / part.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-27  |  27.6 KB  |  818 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <dos.h>
  5. #include <conio.h>
  6. #include <bios.h>
  7.  
  8. char version[] = "Version:  Mk 1.5     27 October 1993" ;
  9.  
  10. #define FALSE        0
  11. #define TRUE        1
  12. #define LOC_PT        0x1BE
  13. #define LOC_NT        0x1AA 
  14. #define LOC_GWR        0x1A9 
  15. #define MAGIC_LOC    0x1FE
  16. #define MAGIC_0        0x55
  17. #define MAGIC_1        0xAA
  18. #define NT_ENTRY_SIZE    5 
  19. #define SECSIZE        0x200
  20. #define sw_printf    if (sw_fancy) printf
  21.  
  22. struct disk_param {
  23.     unsigned int cyl ;
  24.     unsigned int head ;
  25.     unsigned int sect ;
  26. };
  27.  
  28. /* Global variables */
  29. int sw_help = FALSE, sw_null = FALSE, sw_number = FALSE ;
  30. int sw_bios = FALSE, sw_ide = FALSE, sw_details = FALSE, sw_fancy = TRUE ;
  31. unsigned int device = 0 ;
  32.  
  33. /* MAIN PROGRAM --- MAIN PROGRAM --- MAIN PROGRAM --- MAIN PROGRAM */
  34. int main (argc, argv)
  35. /***************************************************************/
  36. /*                                                             */
  37. /*  --- Partition Table and Hard Disk Examination Program ---  */
  38. /*                                                             */
  39. /*  Some code used by this program was derived from:           */
  40. /*      Pfdisk, Version 1.2.1 by Gordon W. Ross, Aug. 1990     */
  41. /*          and later modified by S. Lubkin  Oct. 1991         */
  42. /*      Dug_ide, Version 1.0 by Doug Merrett, 12 Jan 1993      */
  43. /*                                                             */
  44. /* Both programs like this program are public domain freeware. */
  45. /*                                                             */
  46. /*          (c) Copyright 1993 by Gary A. Allen, Jr.           */
  47. /*            Program written by Gary A. Allen, Jr.            */
  48. /*            Version:  Mk 1.5      27 October 1993            */
  49. /*                                                             */
  50. /***************************************************************/
  51.  
  52. int argc ;
  53. char *argv[] ;
  54. {
  55. register int i, j ;
  56.  
  57. int num_drv_bios, num_drv_act ;            /* Number of Hard disks */
  58. int useNTable;        /* boot sector uses name table */
  59. int cyl_bgn[4], cyl_lst[4], head_bgn[4], head_end[4] ;
  60. int sect_bgn[4], sect_end[4], type_code[4] ;
  61. int sw_active[4] ;
  62.  
  63. unsigned int dd[256];         /* Disk Data */
  64. unsigned int pbc,pbh,pbs;    /* physical beginning  c,h,s */
  65. unsigned int pec,peh,pes;    /* physical ending     c,h,s */
  66.  
  67. char chr, cmd[8] ;
  68. char *prt_nam[4], *output_string ;
  69. char buffer[SECSIZE];    /* The boot block buffer */
  70. char *active;
  71.  
  72. long sect_str[4], sect_lng[4] ;
  73.  
  74. unsigned long lsbeg,lslen;    /* logical sectors: begin, length */
  75.  
  76. static char fancy1[81] = {
  77. 0xc9,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd1,0xcd,0xcd,
  78. 0xcd,0xcd,0xd1,0xcd,0xcd,0xcd,0xcd,0xd1,0xcd,0xcd,
  79. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  80. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd1,0xcd,
  81. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  82. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd1,
  83. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd1,
  84. 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xbb,
  85. 0} ;
  86. static char fancy2[] =
  87.     "\xba Part \xb3" "Type\xb3" "Boot\xb3" "     Beginning"
  88.     "      \xb3" "      Ending        \xb3"
  89.     "Starting \xb3" "Number of\xba" ;
  90.  
  91. static char plain1[] =
  92.     "  Part  Type Boot      Beginning             Ending         "
  93.     "Starting  Number of\n" ;
  94.  
  95. static char fancy3[] =
  96.     "\xba" " Type \xb3" "Code\xb3" "Part\xb3" "Side Cylinder Sector\xb3"
  97.     "Side Cylinder Sector\xb3" 
  98.     " Sector  \xb3" " Sectors \xba";
  99.  
  100. static char plain2[] =
  101.     "  Type  Code Part Side Cylinder Sector "
  102.     "Side Cylinder Sector  Sector    Sectors \n";
  103.  
  104. static char fancy4[81] = {
  105.     0xcc,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd8,0xcd,0xcd,
  106.     0xcd,0xcd,0xd8,0xcd,0xcd,0xcd,0xcd,0xd8,0xcd,0xcd,
  107.     0xcd,0xcd,0xd1,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  108.     0xcd,0xd1,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd8,0xcd,
  109.     0xcd,0xcd,0xcd,0xd1,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  110.     0xcd,0xcd,0xd1,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd8,
  111.     0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xd8,
  112.     0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xb9,
  113. 0} ;
  114.  
  115. static char fancy5[] =
  116. "\xba" "%6.6s\xb3" "%#4x\xb3" "%4.4s\xb3" "%3u \xb3" "%7u \xb3" "%5u \xb3"
  117. "%3u \xb3" "%7u \xb3" "%5u \xb3" "%8lu \xb3" "%8lu \xba" ;
  118.  
  119. static char plain3[] =
  120. " %6.6s %#4x %4.4s %3u  %7u  %5u  %3u  %7u  %5u  %8lu  %8lu \n" ;
  121.  
  122. static char fancy6[81] = {
  123.     0xc7,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc5,0xc4,0xc4,
  124.     0xc4,0xc4,0xc5,0xc4,0xc4,0xc4,0xc4,0xc5,0xc4,0xc4,
  125.     0xc4,0xc4,0xc5,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
  126.     0xc4,0xc5,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc5,0xc4,
  127.     0xc4,0xc4,0xc4,0xc5,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
  128.     0xc4,0xc4,0xc5,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc5,
  129.     0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc5,
  130.     0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xb6,
  131. 0} ;
  132.  
  133. static char fancy7[81] = {
  134.     0xc8,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcf,0xcd,0xcd,
  135.     0xcd,0xcd,0xcf,0xcd,0xcd,0xcd,0xcd,0xcf,0xcd,0xcd,
  136.     0xcd,0xcd,0xcf,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  137.     0xcd,0xcf,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcf,0xcd,
  138.     0xcd,0xcd,0xcd,0xcf,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
  139.     0xcd,0xcd,0xcf,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcf,
  140.     0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcf,
  141.     0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xbc,
  142. 0} ;
  143.  
  144. struct part {    /* An entry in the partition table */
  145.     unsigned char    active;        /* active flag (0x80 or 0) */
  146.     unsigned char    b_head;        /* begin head */
  147.     unsigned char    b_sect ;    /*      sector */
  148.     unsigned char    b_cyl;        /*     cylinder */
  149.     unsigned char    sysid;        /* system id */
  150.     unsigned char    e_head;        /* end  head */
  151.     unsigned char    e_sect ;    /* end    sector */
  152.     unsigned char    e_cyl;        /* end    cylinder */
  153.     /* These two are just longs, but this way is machine independent. */
  154.     unsigned long    lsBeg;        /* logical sectors, beginning */
  155.     unsigned long    lsLen;        /* logical sectors, length */
  156. } *pp ;    /* partition table entry */
  157.  
  158. struct disk_param dk, lg, le ;
  159.  
  160. /* Function Prototype */
  161. int getGeometry(int, struct disk_param*) ;
  162. int getBBlk(int, char*) ;
  163. char *getascii(unsigned int in_data[], int off_start, int off_end);
  164. char *nameID(unsigned int);
  165. void listPTable(void) ;
  166. void long2chs(unsigned long, struct disk_param*, struct disk_param*) ;
  167. void switch_list(void) ; 
  168. void cmd_switch(char, int, char *[]) ;
  169. void bugs(void), help(void) ;
  170.  
  171. /* Print heading */
  172. printf("          ") ;
  173. printf("  --- Partition Table and Hard Disk Examination Program ---\n") ;
  174. printf("                    ") ;
  175. printf("  Program written by Gary A. Allen, Jr.          \n") ;
  176. printf("                    ") ;
  177. printf("  %s\n",version) ;
  178. printf("                    ") ;
  179. printf("(c) Copyright 1993 by Gary A. Allen, Jr.\n\n") ;
  180.  
  181. /* Scan the after the dos command PART.EXE for switches or file name */
  182. if (argc > 1) {
  183. for (i = 1; i <= argc-1; i++) {
  184.     /* Flush command vector */
  185.     for (j = 0; j <= 7; j++) cmd[j] = '\0' ;
  186.     /* Get command vector */
  187.     sscanf(argv[i],"%c%c%c%c%c%c%c%c%c", &chr, &cmd[0], &cmd[1],
  188.         &cmd[2], &cmd[3], &cmd[4], &cmd[5], &cmd[6], &cmd[7]) ;
  189.     sw_null = FALSE ;
  190.     if (chr == '?') help() ;
  191.     if (chr == '-') {
  192.         for (j = 0; j <= 7; j++) {
  193.             cmd_switch(cmd[j], i, argv) ;
  194.             if (sw_number) {
  195.                 i++ ;
  196.                 sw_number = FALSE ;
  197.                 break ;
  198.             }
  199.             if (sw_null) break ;
  200.         } /* end of command "for" loop */
  201.  
  202.         if (j >= 7) {
  203. printf("\n!!!! Too many commands on one \"-\" switch group.\n") ;
  204. printf("!!!! Break up the commands into several \"-\" switch groups.\n") ;
  205.             bugs() ;
  206.         }
  207.     } /* end of the "-" marker block */
  208.  
  209.     /* Deal with garbage on the command line */
  210.     else {
  211. printf ("\n!!!! The following on the command line was not understood:  %s \n",
  212.     argv[i]);
  213.         bugs() ;
  214.     } /* garbage block */
  215.  
  216. } /* end of argument token "for" loop */
  217.  
  218. if (sw_help) help() ;
  219. } /* end of the command switch block */
  220.  
  221. /* determine actual number of disk drives */
  222. num_drv_act = 0 ;
  223. while (!getGeometry(num_drv_act++,&dk)) ;
  224. num_drv_act-- ;
  225.  
  226. if (num_drv_act == 0) {
  227. printf("!!!! There is no hard disk on this computer!\n") ;
  228.     bugs() ;
  229. }
  230.  
  231. /* State the drive number */
  232. if (num_drv_act != 1) printf("Describing hard disk #%d\n", device);
  233.  
  234. /* Ask BIOS how many disk drives there are */
  235. /* Byte at Segment 40H Offset 75H */
  236. num_drv_bios = peekb(0x40, 0x75) ;  /* BIOS Data area, Number of Hard disks */
  237.  
  238. /* Say how many drives are on this machine if the number is interesting */
  239. if ((num_drv_act != num_drv_bios) || num_drv_act > 1) {
  240. printf("BIOS reports %d hard disk(s) but ", num_drv_bios) ;
  241. printf("there are actually %d disk(s) on this computer.\n", num_drv_act) ;
  242. }
  243.  
  244. /* Deal with the error of asking for the wrong disk drive */
  245. if ((device + 1) > num_drv_act) {
  246. printf("!!!! There are only %d hard disk(s) on this computer but you\n",
  247.     num_drv_act);
  248. printf("!!!! requested disk #%d (master disk is disk #0).\n", device);
  249.     bugs() ;
  250. }
  251.  
  252. /* get disk parameters */
  253. if (getGeometry(device,&dk)) {
  254. printf("!!!! Function getGeometry found device %d not valid.\n", device);
  255.     bugs() ;
  256. }
  257.  
  258. /* Get the boot block. */
  259. if (getBBlk(device, buffer) < 0) {
  260.     printf("!!!! Could not read device number %d.\n", device);
  261.     bugs() ;
  262. }
  263.  
  264. /* Check the magic number. */
  265. if ((buffer[MAGIC_LOC] & 0xFF) != MAGIC_0 ||
  266.       (buffer[MAGIC_LOC+1] & 0xFF) != MAGIC_1) {
  267. printf("\nWarning:  The boot sector has been found to have an invalid\n") ;
  268. printf("magic number!  Do not reboot the hard disk until you fix this\n") ;
  269. printf("problem.  You will need a partition editor like Pfdisk, Edpart\n") ;
  270. printf("or the Norton Utility to do the fix.\n\n") ;
  271. } /* end of the magic number "if" block */
  272.  
  273. /* Does it use a name table (for a boot menu)?     */
  274. useNTable = ( buffer[LOC_GWR] == (char)0x3A );
  275.  
  276. /* Get IDE Drive info */
  277. if (sw_ide) {
  278.     while (inportb(0x1F7) != 0x50) ; /* Wait for controller not busy */
  279.  
  280.     /* Get first/second drive */
  281.     outportb(0x1F6, (device == 0 ? 0xA0 : 0xB0));
  282.  
  283.     /* Get drive info data */
  284.     outportb(0x1F7, 0xEC);         
  285.  
  286.     /* Wait for data ready */
  287.     while (inportb(0x1F7) != 0x58) ;
  288.  
  289.     /* Read "sector" */
  290.     for (i = 0; i < 256; i++) dd[i] = inport(0x1F0);
  291.  
  292.     if (sw_details) {
  293. printf("Model Number ---------------------> %s\n", getascii(dd, 27, 46));
  294. /* 
  295. printf("Serial Number --------------------> %s\n", getascii(dd, 10, 19));
  296. */
  297. printf("Controller Revision Number -------> %s\n", getascii(dd, 23, 26));
  298. printf("Able to do Double Word Transfer --> %6s\n",
  299.     (dd[48] == 0 ? "No" : "Yes"));
  300. printf("Controller type ------------------>   %04X\n", dd[20]);
  301. printf("Controller buffer size (bytes) ---> %6u\n", dd[21] * 512);
  302. printf("Number of ECC bytes transferred --> %6u\n", dd[22]);
  303. printf("Number of sectors per interrupt --> %6u\n\n", dd[47]);
  304.     } /* end of the "ide details" block */
  305.  
  306.     printf("IDE  reports %d cylinders, %d heads (tracks) and"
  307.         " %d sectors/cylinder for a\n", dd[1], dd[3], dd[6]) ;
  308.     printf("     total (unformatted) capacity of %ld bytes.\n",
  309.         (long) dd[1] * (long) dd[3] * (long) dd[6] * 512L) ;
  310.     if ((!sw_bios) && (!sw_details)) printf("\n") ;
  311. } /*  end of the "ide" block */
  312.  
  313. /* Display BIOS disk data */
  314. if (sw_bios) {
  315.     printf("BIOS reports %d cylinders, %d heads (tracks) and"
  316.         " %d sectors/cylinder for a\n", dk.cyl, dk.head, dk.sect);
  317.     printf("     total (unformatted) capacity of %ld bytes.\n",
  318.          (long) dk.cyl * (long) dk.head * (long) dk.sect * 512L) ;
  319.     if (!sw_ide) printf("\n") ;
  320. }
  321.  
  322. if ((sw_ide && sw_bios) || sw_details) {
  323. printf("               [Press \"q\" to quit or any other key to continue]") ;
  324.         chr = getche() ;
  325. printf("\r                                                                 \n");
  326.         if ((chr == 'q')||(chr == 'Q')) exit(0) ;
  327. }
  328.  
  329. /* Scan the four partitions */
  330. for (i = 0; i < 4; i++) {
  331.     pp = (struct part *) &buffer[LOC_PT + i * 16];
  332.  
  333.     if (pp->active) {
  334.         if (pp->active != 0x80)
  335. printf("\nWarning: Partition %d is active, with the illegal activity byte %d\n",
  336.     i+1, pp->active);
  337.         sw_active[i] = TRUE ;
  338.     }
  339.     else sw_active[i] = FALSE ;
  340.  
  341.     /* physical beginning c,h,s */
  342.     pbc = (pp->b_cyl & 0xff) | ((pp->b_sect << 2) & 0x300) ;
  343.     pbh = pp->b_head;
  344.     pbs = pp->b_sect & 0x3F;
  345.  
  346.     /* physical ending c,h,s */
  347.     pec = (pp->e_cyl & 0xff) | ((pp->e_sect << 2) & 0x300) ;
  348.     peh = pp->e_head;
  349.     pes = pp->e_sect & 0x3F;
  350.  
  351.     /* compute logical beginning */
  352.     lsbeg = pp->lsBeg;
  353.     long2chs(lsbeg, &lg, &dk) ;
  354.  
  355.     /* compute logical ending */
  356.     lslen = pp->lsLen;
  357.     /* keep beginning <= end ... */
  358.     if (lslen > 0) long2chs(lsbeg+lslen-1, &le, &dk) ;
  359.     else long2chs(lsbeg, &le, &dk) ;
  360.  
  361.     if (useNTable) {
  362.         prt_nam[i] = &buffer[LOC_NT + i * NT_ENTRY_SIZE ];
  363.         type_code[i] = 0 ;
  364.     }
  365.     else {
  366.         prt_nam[i] = nameID((unsigned int) pp->sysid);
  367.         type_code[i] = (int) pp->sysid ;
  368.     }
  369.  
  370.     cyl_bgn[i] = pbc ;
  371.     cyl_lst[i] = le.cyl ;
  372.     sect_str[i] = lsbeg ;
  373.     sect_lng[i] = lslen ;
  374.     head_bgn[i] = pbh ;
  375.     head_end[i] = peh ;
  376.     sect_bgn[i] = pbs ;
  377.     sect_end[i] = pes ;
  378.  
  379.     /* That's all, for an empty partition. */
  380.     if (pp->sysid == 0) continue;
  381.  
  382.     /* Now do some consistency checks...  */
  383.  
  384.     /* Same physical / logical beginning? */
  385.     if (pbc != lg.cyl || pbh != lg.head || pbs != lg.sect ) {
  386. printf("\nWarning: For partition %d\n", i+1);
  387. printf("Physical beginning = %d cyl., %d head, %d sector\n", pbc, pbh, pbs);
  388. printf("Logical beginning  = %d cyl., %d head, %d sector\n\n",
  389.         lg.cyl, lg.head, lg.sect);
  390.     }
  391.     /* Same physical / logical ending? */
  392.     if (pec != le.cyl || peh != le.head || pes != le.sect ) {
  393. printf("\nWarning: For partition %d\n", i+1);
  394. printf("Physical ending = %d cyl., %d head, %d sector\n", pec, peh, pes);
  395. printf("Logical ending  = %d cyl., %d head, %d sector\n\n",
  396.         le.cyl, le.head, le.sect);
  397.     }
  398.  
  399.     /* Beginning on cylinder boundary? */
  400.     if (pbc == 0) { /* exception: start on head 1 */
  401.         if (pbh != 1 || pbs != 1) {
  402. printf("\nWarning: Partition %d does not start on head 1.\n", i+1);
  403. printf("Physical beginning = %d cyl., %d head, %d sector\n", pbc, pbh, pbs);
  404. printf("         should be = %d cyl.,  1 head,  1 sector\n\n", pbc) ;
  405.         }
  406.     }
  407.     else { /* not on cyl 0 */
  408.         if (pbh != 0 || pbs != 1) {
  409. printf("\nWarning: Partition %d does not start on head 0.\n", i+1);
  410. printf("Physical beginning = %d cyl., %d head, %d sector\n", pbc, pbh, pbs);
  411. printf("         should be = %d cyl.,  0 head,  1 sector\n\n", pbc) ;
  412.              }
  413.        }
  414.  
  415.     /* Ending on cylinder boundary? */
  416.     if (peh != (dk.head-1) || pes != dk.sect) {
  417. printf("\nWarning: Partition %d does not end on a cylinder boundary.\n", i+1);
  418. printf("Physical ending = %d cyl., %d head, %d sector\n", pec, peh, pes);
  419. printf("      should be = %d cyl., %d head, %d sector\n\n",
  420.         pec,dk.head-1, dk.sect);
  421.     }
  422.  
  423. } /* end of partition "for" loop */
  424.  
  425. /* showboot begins here */
  426. sw_printf(fancy1);
  427. sw_printf(fancy2);
  428. else printf(plain1);
  429. sw_printf(fancy3);
  430. else printf(plain2);
  431. sw_printf(fancy4);
  432.  
  433. if (sw_fancy) output_string = fancy5 ;
  434. else output_string = plain3 ;
  435.  
  436. for (i = 0; i < 4; ++i) {
  437.     if (sw_active[i]) active = "YES" ;
  438.     else active = " NO";
  439.  
  440.     printf(output_string, prt_nam[i], type_code[i], active,
  441.                  head_bgn[i], cyl_bgn[i], sect_bgn[i],
  442.                  head_end[i], cyl_lst[i], sect_end[i],
  443.                  sect_str[i], sect_lng[i]);
  444.  
  445.     if ((i < 3) && sw_fancy) printf(fancy6);
  446. }
  447. sw_printf(fancy7);
  448. printf("\n\"Part\" has ended normally.  If you are interested in more ") ;
  449. printf("information about\nthis program then type:  part -h \n");
  450. return(0) ;
  451. } /* --- end of the "main" routine. --- */
  452.  
  453. void long2chs(unsigned long ls, struct disk_param *lg, struct disk_param *dk)
  454. {
  455. int spc ;
  456.  
  457. spc = dk->head * dk->sect ;
  458. lg->cyl = (int)(ls / spc) ;
  459. ls = ls % spc;
  460. lg->head = (int)(ls / dk->sect) ;
  461. lg->sect = (int)(ls % dk->sect + 1) ;    /* sectors count from 1 */
  462. } /* -- end of the "long2chs" subroutine -- */
  463.  
  464. char *nameID(unsigned int input_code)
  465. {
  466. struct intString {
  467.     unsigned int code ;
  468.     char *strg;
  469. } *is ;
  470. struct intString sysCodes[44] = {
  471.     { 0x01, "DOS-12  :12-bit FAT" },
  472.     { 0x02, "XENIX   :root" },
  473.     { 0x03, "XENIX   :usr" },
  474.     { 0x04, "DOS-16  :16-bit FAT" },
  475.     { 0x05, "DOSext  :DOS 3.3 extended volume" },
  476.     { 0x06, "DOSbig  :DOS 4.0 large volume" },
  477.     { 0x07, "OS/2    :OS/2 (or QNX or Adv. UNIX...)" },
  478.     { 0x08, "AIX     :file system" },
  479.     { 0x09, "AIXbt   :boot partition" },
  480.     { 0x0a, "BootMg  :OS/2 Boot Manager" },
  481.     
  482.     { 0x10, "OPUS    :?" },
  483.     { 0x11, "DOS     :DOS seen from OS/2" },
  484.     { 0x17, "HPFS    :OS/2 High Performance File System" },
  485.     { 0x40, "VENIX   :Venix 80286" },
  486.     { 0x51, "NOVEL  :?" },
  487.     { 0x52, "CPM     :?" },
  488.     { 0x63, "UNIX    :System V/386" },
  489.     { 0x64, "NOVEL  :?" },
  490.     { 0x75, "PC/IX   :?" },
  491.     { 0x80, "Minix   :Minix (ver. 1.4a and earlier)" },
  492.     { 0x81, "Minix   :Minix (ver. 1.4b and later)" },
  493.     { 0x93, "Ameba  :Amoeba file system" },
  494.     { 0x94, "Ameba  :Amoeba bad block table?" },
  495.     { 0xA5,    "386BSD  :?" },
  496.     { 0xDB,    "C.DOS   :Concurrent DOS" },
  497.  
  498.     /* { 0xF2, "DOS-2nd :DOS 3.3+ second partition" }, */
  499.     /* { 0xFF, "BAD-TRK :Bad track table?" }, */
  500.  
  501.     /* Make sure this is last! */
  502.     {    0, "Empty " }
  503. };
  504.  
  505. is = sysCodes;
  506. while (is->code) {
  507.     if (is->code == input_code) return(is->strg);
  508.     is++;
  509. }
  510. if (!input_code) return(is->strg);
  511. return("Unknwn");
  512. } /* --- end of the "nameID" function --- */
  513.  
  514. int getGeometry(int dev, struct disk_param *pnt)
  515. {
  516. union REGS regs;
  517. struct SREGS sregs;
  518.   
  519. regs.h.ah = 8;        /* get param.    */
  520. regs.h.dl = dev | 0x80;
  521.   
  522. int86x(0x13,®s,®s,&sregs);
  523.   
  524. /* Are that many drives responding? */
  525. if ((regs.h.dl <= dev)||(regs.x.cflag)) return(1) ;
  526. pnt->cyl = ((((int) regs.h.cl << 2) & 0x300) | regs.h.ch) + 2;
  527. pnt->head = regs.h.dh + 1;
  528. pnt->sect = regs.h.cl & 0x3F;
  529. return(0) ;
  530. } /* --- end of the function "getGeometry" --- */
  531.  
  532. int getBBlk(int dev, char *buf)
  533. {    /* BIOS absolute disk read */
  534. union REGS regs;
  535. struct SREGS sregs;
  536.   
  537. segread(&sregs);    /* get ds */
  538. sregs.es = sregs.ds;    /* buffer address */
  539. regs.x.bx = (int) buf;
  540.   
  541. regs.h.ah = 2;        /* read        */
  542. regs.h.al = 1;        /* sector count    */
  543. regs.h.ch = 0;        /* track    */
  544. regs.h.cl = 1;        /* start sector    */
  545. regs.h.dh = 0;        /* head        */
  546. regs.h.dl = dev | 0x80;    /* drive    */
  547.   
  548. int86x(0x13,®s,®s,&sregs);
  549. if (regs.x.cflag) {
  550.     printf("Function getBBlk found device %d not valid.\n", dev);
  551.     return(-1);
  552. }
  553. return(SECSIZE);
  554. } /* --- end of the "getBBlk" function --- */
  555.  
  556. void bugs(void)
  557. /***************************************************************/
  558. /*                                                             */
  559. /*          (c) Copyright 1993 by Gary A. Allen, Jr.           */
  560. /*            Program written by Gary A. Allen, Jr.            */
  561. /*             Version:  Mk 1.0     24 October 1993            */
  562. /*                                                             */
  563. /***************************************************************/
  564. {
  565. printf("!!!! If confused, type:  part -h \n");
  566. printf("!!!! --- Program ABORTED --- \n");
  567. exit(0) ;
  568. } /* --- end of the "bugs" subroutine --- */
  569.  
  570. void help(void) 
  571. /*****************************************************/
  572. /*                                                   */
  573. /*                    Help Routine                   */
  574. /*                                                   */
  575. /*      (c) Copyright 1993 by Gary A. Allen, Jr.     */
  576. /*        Program written by Gary A. Allen, Jr.      */
  577. /*        Version:  Mk 1.0    24 October 1993        */
  578. /*                                                   */
  579. /*****************************************************/
  580. {
  581. printf("The following command line switches are recognized:\n");
  582. printf("    -?  or -H    =    You typed this to get this output.\n");
  583. switch_list() ;
  584. exit(0);
  585. } /* ---- end of the "help" subroutine ---- */
  586.  
  587. void description(void)
  588. /***************************************************************/
  589. /*                                                             */
  590. /*          (c) Copyright 1993 by Gary A. Allen, Jr.           */
  591. /*            Program written by Gary A. Allen, Jr.            */
  592. /*             Version:  Mk 1.0     24 October 1993            */
  593. /*                                                             */
  594. /***************************************************************/
  595. {
  596. char chr ;
  597.  
  598. printf("          "
  599.     "You are free to use, copy and distribute \"Part\" provided:\n") ;
  600. printf("          "
  601.     "       NO FEE IS CHARGED FOR USE, COPYING OR DISTRIBUTION.\n") ;
  602. printf("          "
  603.     "       THIS PROGRAM IS FOR PRIVATE, NONCOMMERICAL USE ONLY.\n") ;
  604. printf("          "
  605.     "       THE PROGRAM MAY NOT BE MODIFIED IN ANY WAY.\n\n") ;
  606. printf("          "
  607.     "Some code used by this program was derived from:\n") ;
  608. printf("          "
  609.     "       Pfdisk, Version 1.2.1 by Gordon W. Ross, Aug. 1990\n") ;
  610. printf("          "
  611.     "            and later modified by S. Lubkin  Oct. 1991\n") ;
  612. printf("          "
  613.     "       Dug_ide, Version 1.0 by Doug Merrett, 12 Jan 1993\n") ;
  614.  
  615. /* keep the screen from scrolling */
  616. printf("               [Press \"q\" to quit or any other key to continue]") ;
  617. chr = getche() ;
  618. printf("\r                                                                 \n");
  619. if ((chr == 'q')||(chr == 'Q')) exit(0) ;
  620.  
  621. printf("         "
  622.     "DISCLAIMER: \"Part\" is offered on an as-is-basis without  any\n") ;
  623. printf("         "
  624.     "warranty to the  correct  functioning  or  fitness  for  any\n") ;
  625. printf("         "
  626.     "specific purpose.  To the  extent  permitted  by  applicable\n") ;
  627. printf("         "
  628.     "law,  the  author  disclaims  all  warranties,  expressed or\n") ;
  629. printf("         "
  630.     "implied, including but not limited to, any implied  warranty\n") ;
  631. printf("         "
  632.     "of merchantability or  fitness  for  a  particular  purpose.\n") ;
  633. printf("         "
  634.     "While effort has been made to ensure that  this  program  is\n") ;
  635. printf("         "
  636.     "accurate and correct, the author shall  not  be  liable  for\n") ;
  637. printf("         "
  638.     "damages arising out of the use of or inability to  use  this\n") ;
  639. printf("         "
  640.     "product, including but not limited to, loss of profit, data,\n") ;
  641. printf("         "
  642.     "or  use  of  this  software,  or  special,  incidental,   or\n") ;
  643. printf("         "
  644.     "consequential damages or other similar claims, even  if  the\n") ;
  645. printf("         "
  646.     "author has been specifically advised of the  possibility  of\n") ;
  647. printf("         "
  648.     "such  damages.  Some states do not allow  the  exclusion  of\n") ;
  649. printf("         "
  650.     "incidental or consequential damages.  The  author  prohibits\n") ;
  651. printf("         "
  652.     "the use of this program in such states.\n") ;
  653.  
  654. /* keep the screen from scrolling */
  655. printf("               [Press \"q\" to quit or any other key to continue]") ;
  656. chr = getche() ;
  657. printf("\r                                                                 \n");
  658. if ((chr == 'q')||(chr == 'Q')) exit(0) ;
  659.  
  660. printf("This program is strictly \"read-only\" and should never modify"
  661.     "  the   partition\n") ;
  662. printf("table or write to your  hard  disk.   You  can  safely  experiment"
  663.     "  with  the\n") ; 
  664. printf("executable, using any combination of switches without danger of"
  665.     " damaging  the\n") ; 
  666. printf("data on your hard disk.  The IDE data might be spurious if the hard"
  667.     " disk does\n") ; 
  668. printf("not have an IDE controller, i.e. it's a SCSI or ESDI.  If \"Part\""
  669.     " encounters a\n") ; 
  670. printf("corrupted hard disk then it might issue warnings.  If this should"
  671.     " happen then\n") ; 
  672. printf("you are strongly  advised  to  backup  all  data  on  the  disk  and"
  673.     "  attempt\n") ; 
  674. printf("restoration of the partition table before you reboot.\n\n") ;
  675.  
  676. printf("When corresponding please state which version of \"Part\" you are ") ;
  677. printf("using. \n") ;
  678. printf("Questions and complaints about this program should be sent to:\n\n") ;
  679. printf("          E-mail address:     gary@brolga.cc.uq.oz.au\n") ;
  680. printf("          Postal address:     Gary A. Allen, Jr. \n") ;
  681. printf("                              P.O. Box 13\n") ;
  682. printf("                              St. Lucia, Queensland  4067\n") ;
  683. printf("                              Australia\n") ;
  684. exit (0) ; 
  685. } /* --- end of the "description" subroutine --- */
  686.  
  687. char *getascii(unsigned int in_data[], int off_start, int off_end)
  688. {
  689. register int i ;
  690. char *pnt ;
  691. static char ret_val[255];
  692.  
  693. pnt = ret_val ;
  694.  
  695. for (i = off_start; i <= off_end; i++) {
  696.     *(pnt++) = (char) (in_data[i] / 256);  /* Get High byte */
  697.     *(pnt++) = (char) (in_data[i] % 256);  /* Get Low byte */
  698. }
  699. *pnt = '\0';  /* Make sure it ends in a NULL character */
  700.  
  701. return(ret_val);
  702. } /* --- end of the subroutine "getascii" --- */
  703.  
  704. void cmd_switch(char cmd, int i_point, char *argv[])
  705. /*****************************************************/
  706. /*                                                   */
  707. /*         --- Command line Switch Parser ---        */
  708. /*                                                   */
  709. /*      (c) Copyright 1993 by Gary A. Allen, Jr.     */
  710. /*        Program written by Gary A. Allen, Jr.      */
  711. /*           Version:  Mk 1.1   24 October 1993      */
  712. /*                                                   */
  713. /*****************************************************/
  714. {
  715. void switch_list(void), description(void) ; 
  716.  
  717. switch (cmd) {
  718.     case '\0':
  719.     case -1:
  720.         sw_null = TRUE ;
  721.         return ;
  722.  
  723.     /* Get BIOS hard disk configuration data */
  724.     case 'b':
  725.     case 'B':
  726.         sw_bios = TRUE ;
  727.         return ;
  728.  
  729.     /* Select the disk drive to be examined */
  730.     case 'd':
  731.     case 'D':
  732.         sw_number = TRUE ;
  733.         device = atoi(argv[i_point+1]) ;
  734.         return ;
  735.  
  736.     /* Get IDE hard disk configuration data */
  737.     case 'I':
  738.         sw_details = TRUE ;
  739.     case 'i':
  740.         sw_ide = TRUE ;
  741.         return ;
  742.  
  743.     case 'x':
  744.     case 'X':
  745.         sw_fancy = FALSE ;
  746.         return ;
  747.  
  748.     case 'z':
  749.     case 'Z':
  750.         description() ;
  751.  
  752.     /* Help option */
  753.     case '?':
  754.     case 'h':
  755.     case 'H':
  756.         sw_help = TRUE ;
  757.         return ;
  758.  
  759.     case ' ':
  760.     case '-':
  761.     case '1':
  762.     case '2':
  763.     case '3':
  764.     case '4':
  765.     case '5':
  766.     case '6':
  767.     case '7':
  768.     case '8':
  769.     case '9':
  770.         return ;
  771.     default:
  772. printf("Command line switch -%c is unknown.  The following command\n",cmd) ;
  773. printf("line switches are recognized:\n");
  774. printf("    -?  or -H    =    Explains how to use this program.\n");
  775. switch_list() ;
  776. printf("\n                  *** Program PART aborted *** \n") ;
  777.                     exit(0) ;
  778. }
  779. } /* --- end of the cmd_switch subroutine --- */
  780.  
  781. void switch_list(void) 
  782. /*****************************************************/
  783. /*                                                   */
  784. /*          --- Command line Switch List ---         */
  785. /*                                                   */
  786. /*      (c) Copyright 1993 by Gary A. Allen, Jr.     */
  787. /*        Program written by Gary A. Allen, Jr.      */
  788. /*           Version:  Mk 1.3   3 October 1993       */
  789. /*                                                   */
  790. /*****************************************************/
  791. {
  792. /*
  793. char chr ;
  794. */
  795.  
  796. printf("    -b     -B    =    Show BIOS data for the hard disk(s)\n") ;
  797. printf("                      specified.\n") ;
  798. printf("    -d #   -D #  =    Select a specific hard drive to be examined\n") ;
  799. printf("                      where \"# = 0\" is the master hard disk.\n") ;
  800. printf("    -i           =    Show IDE data for total number of cylinders,\n") ;
  801. printf("                      heads and number of sectors/track (cylinder)\n");
  802. printf("           -I    =    Show detailed data about the IDE controller\n") ;
  803. printf("                      along with total number of cylinders, etc.\n") ;
  804. printf("    -x     -X    =    No fancy display format. Output becomes less\n");
  805. printf("                      readable but is plain ASCII and will not\n") ;
  806. printf("                      confuse other programs or strange terminals.\n") ;
  807. printf("    -z     -Z    =    Describe this program, make legal disclamer\n") ;
  808. printf("                      and mention any known bugs.\n") ;
  809.  
  810. /* keep the screen from scrolling */
  811. /*
  812. printf("               [Press \"q\" to quit or any other key to continue]") ;
  813. chr = getche() ;
  814. printf("\r                                                                 \n");
  815. if ((chr == 'q')||(chr == 'Q')) exit(0) ;
  816. */
  817. } /* --- end of the switch_list subroutine --- */
  818.